package com.dashan.frontend.client.widgets;

import java.util.HashMap;

import com.dashan.frontend.client.EventBus;
import com.dashan.frontend.client.event.GeoItemSelectedEvent;
import com.dashan.frontend.client.event.GeoItemSelectedHandler;
import com.dashan.frontend.client.util.GoogleMap;
import com.google.gwt.dom.client.Element;
import com.google.gwt.maps.client.overlay.Marker;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.grid.event.GridRowListenerAdapter;

public class GeoGridPanel extends GridPanel implements GeoItemSelectedHandler {
    static public class GeoRecord {
        Record record;
        Marker marker;
        
        public GeoRecord(Record record, Marker marker) {
            this.record = record;
            this.marker = marker;
        }
        
        public Record getRecord() {
            return record;
        }
        
        public Marker getMarker() {
            return marker;
        }
    }
    
    class MyGridRowListener extends GridRowListenerAdapter {
        @Override
        public void onRowClick(GridPanel grid, int rowIndex, EventObject e) {
            super.onRowClick(grid, rowIndex, e);
            EventBus.get().fireEvent(new GeoItemSelectedEvent(getRecord(rowIndex)));
        }
        @Override
        public void onRowDblClick(GridPanel grid, int rowIndex, EventObject e) {
            super.onRowDblClick(grid, rowIndex, e);
            EventBus.get().fireEvent(new GeoItemSelectedEvent(getRecord(rowIndex), true));
        }
    }
    
    private static final String SELECTED_ROW_CLASS = "x-grid3-row-selected";
    
    private GoogleMap map;
   
    private Store store;
    private int currentSelectionIdx = -1;
    private HashMap<Marker, GeoRecord> geoStore = new HashMap<Marker, GeoRecord>();
    private GeoItemSelectedHandler selectHandler = null;
    
    
    
    public GeoGridPanel(GoogleMap map, RecordDef recordDef) {
        this.map = map;
        store = new Store(recordDef);
        this.setStore(store);
        this.addGridRowListener(new MyGridRowListener());
        
        EventBus.get().addHandler(GeoItemSelectedEvent.TYPE, this);
    }
    
    public GeoGridPanel(GoogleMap map, Store store) {
        this.map = map;
        this.store = store;
        this.setStore(this.store);
        this.addGridRowListener(new MyGridRowListener());
        
        EventBus.get().addHandler(GeoItemSelectedEvent.TYPE, this);
    }

    public void addGeoRecord(GeoRecord geoRecord) {
        store.add(geoRecord.record);
        if (geoRecord.marker != null) {
            geoStore.put(geoRecord.marker, geoRecord);
            map.addMarker(geoRecord.marker);
        }
    }
    
    public void hideMarker() {
        for (Marker m : geoStore.keySet()) {
            map.removeMarker(m);
        }
    }
    
    public void showMarker() {
        for (Marker m : geoStore.keySet()) {
            map.addMarker(m);
        }
    }
    public void clearData() {
        hideMarker();
        store.removeAll();
        
    }
    public void setItemSelectedHandler(GeoItemSelectedHandler handler) {
        this.selectHandler = handler;
    }
    
    @Override
    public void onGeoItemSelected(GeoItemSelectedEvent event) {
        int idx = getRecordIndex(event.getGeoRecord().marker);
        if (currentSelectionIdx != -1) {
            Element row = super.getView().getRow(currentSelectionIdx);
            row.setClassName(removeSelectedClass(row.getClassName()));
        }
        currentSelectionIdx = idx;
        if (currentSelectionIdx != -1) {
            super.getView().focusRow(currentSelectionIdx);
            Element row = super.getView().getRow(currentSelectionIdx);
            row.setClassName(removeSelectedClass(row.getClassName()));
            row.setClassName(addSelectedClass(row.getClassName()));
        }
        if (selectHandler != null) {
            selectHandler.onGeoItemSelected(event);
        }
    } 
    
    private int getRecordIndex(Marker m) {
        GeoRecord gr = geoStore.get(m);
        for (int i = 0; i < store.getCount(); i++) {
            Record r = store.getRecordAt(i);
            if (r.getId().compareTo(gr.record.getId()) == 0) {
                return i;
            }
        }
        return -1;
    }
    
    private GeoRecord getRecord(int i) {
        Record r = store.getAt(i);
        for (Marker m : geoStore.keySet()) {
            if (geoStore.get(m).record.getId().compareTo(r.getId()) == 0) {
                return geoStore.get(m);
            }
        }
        return null;
    }
    
    private static String addSelectedClass(String cls) {
        return cls + " " + SELECTED_ROW_CLASS;
    }
    
    private static String removeSelectedClass(String cls) {
        String[] res = cls.split(" ");
        String newCls = "";
        for (String s : res) {
            if (s.compareTo(SELECTED_ROW_CLASS) != 0) {
                newCls += " " + s;
            }
        }
        return newCls;
    }
}
